package com.ys.controller.api.business;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.entity.business.TpShopRegisterPhaseRecord;
import com.ys.entity.business.TpShopRegisterPhaseSet;
import com.ys.entity.sys.YsCol;
import com.ys.service.business.TpShopRegisterPhaseSetService;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.UploadService.UploadDto;
import com.ys.util.ExportExcelUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;

@Controller
@RequestMapping("/api/inter/tpShopRegisterPhaseSet")
public class ApiInterTpShopRegisterPhaseSetController {
	
	@Autowired
	private CommonApiService<TpShopRegisterPhaseSet> commonApiService;
    @Autowired
    private TpShopRegisterPhaseSetService tpShopRegisterPhaseSetService;

    @RequiresPermissions("tpShopRegisterPhaseSet:view")
	@RequestMapping("/searchForPoint")
	@ResponseBody
	public LayuiTableVoJA searchForPoint(@ModelAttribute TpShopRegisterPhaseSet cond){
    	cond.setOrderby("A.PhaseNum asc");
		return commonApiService.searchLay(cond);
	}

    /**
     * 设置查询的cond的sql设置
     * @param cond
     * @return
     */
    public TpShopRegisterPhaseSet setSeachSql(TpShopRegisterPhaseSet cond){
        cond.addField("CASE WHEN A.SetType = 0 THEN '阶段任务' WHEN A.SetType = 1 THEN '分支集合' ELSE '任务分支' END setTypeStr ");//设置类型
        cond.addField("CASE WHEN B.countNum IS NULL AND A.SetType = 0 THEN '0' WHEN A.SetType != 0 THEN null ELSE B.countNum END countNum ");//平均时效
        cond.addField("U.UserId + '/' + U.UserName AS headUser ");//负责人
        cond.addField("UO.DeptName AS deptNameInfo");//负责部门
        cond.addLeftJoin("TS_UserInfo U ON A.HeadUserId = U.UserId ");
        cond.addLeftJoin("TS_OrganizationInfo UO ON UO.Orgid = U.DeptId");
        cond.addLeftJoin(" ( SELECT SUM(WorkTime) / COUNT(Id) AS countNum,SetId  FROM TP_ShopRegisterPhaseRecord GROUP BY SetId) B ON B.SetId = A.Id ");
        cond.setOrderby("A.PhaseNum ASC");//按阶段排序
        return  cond;
    }

	/**
     * 查询
     * @param model
     * @param request
     * @param response
     * @param
     * @return
     */
    @RequiresPermissions("tpShopRegisterPhaseSet:view")
    @RequestMapping("/search")
    @ResponseBody
    public LayuiTableVoJA search(){
        try {
            List<Map<String,Object>> resListNew = new TpShopRegisterPhaseSet()
                    .addField("CASE WHEN A.SetType = 0 THEN '阶段任务' WHEN A.SetType = 1 THEN '分支集合' ELSE '任务分支' END setTypeStr ")//设置类型
                    .addField("CASE WHEN B.countNum IS NULL AND A.SetType = 0 THEN '0' WHEN A.SetType != 0 THEN null ELSE B.countNum END countNum ")//平均时效
                    .addField("U.UserId + '/' + U.UserName AS headUser ")//负责人
                    .addField("U.DeptName AS deptNameInfo")//负责部门
                    .addLeftJoin("TS_UserInfo U ON A.HeadUserId = U.UserId ")
                    .addLeftJoin(" ( SELECT SUM(WorkTime) / COUNT(Id) AS countNum,SetId  FROM TP_ShopRegisterPhaseRecord GROUP BY SetId) B ON B.SetId = A.Id ")
                    .setOrderby("A.PhaseNum ASC")//按阶段排序
                    .queryMap();

            /*
            cond = setSeachSql(cond);
            LayuiTableVoJA setList = commonApiService.searchLay(cond);
            //获取
            JSONArray tableVoJAData = setList.getData();

            //转换
            List<Map> resList = JSONArray.parseArray(JSON.toJSONString(tableVoJAData),Map.class);
            List<Map<String, Object>> resListNew = new ArrayList();
            resList.forEach(item-> resListNew.add(item));

             */
            LayuiTableVoJA setList = new LayuiTableVoJA();
            //递归查询
            List<Map<String, Object>> listData = resListNew.stream().filter(item -> item.get("parentId").toString().equals("-1") )
                    .map(item -> {
                        List<Map<String, Object>> childrensList = getChildrens(item,resListNew);
                        item.put("children", childrensList);
                        item.put("phaseNumTxt", (!item.get("setType").toString().equals("2") ? item.get("phaseNum").toString():"并行"));
                        item.put("isParent", (childrensList!=null&&childrensList.size()>0));
                        //图标
                        item.put("icon", item.get("setType").toString().equals("0") ? "<i class=\"layui-icon layui-icon-flag\"></i>" : (item.get("setType").toString().equals("1") ? "<i class=\"layui-icon layui-icon-template-1\"></i>" : "<i class=\"layui-icon layui-icon-slider\"></i>"));

                        return item;
                    })
                    .collect(Collectors.toList());

            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(listData));
            setList.setData(jsonArray);
            setList.setCode(0);

            return setList;
        }catch (Exception e){
            e.printStackTrace();
            LayuiTableVoJA setList = new LayuiTableVoJA();
            setList.setCode(1);
            setList.setMsg("查询出错，请稍后重试！");
            return setList;
        }
    }

    /**
     * 查询子类数据
     * @param item
     * @param dateList
     * @return
     */
    public List<Map<String, Object>> getChildrens(Map<String, Object> item,List<Map<String, Object>> dateList){
        List<Map<String, Object>> childrens = dateList.stream()
                .filter(dataItem -> dataItem.get("parentId").toString().equals(item.get("id").toString()))
                .map(childrenItem -> {
                    childrenItem.put("phaseNumTxt", (!childrenItem.get("setType").toString().equals("2") ? childrenItem.get("phaseNum").toString():"并行"));
                    //图标
                    childrenItem.put("icon", childrenItem.get("setType").toString().equals("0") ? "<i class=\"layui-icon layui-icon-flag\"></i>" : (childrenItem.get("setType").toString().equals("1") ? "<i class=\"layui-icon layui-icon-template-1\"></i>" : "<i class=\"layui-icon layui-icon-slider\"></i>"));
                    List<Map<String, Object>> childrensList = getChildrens(childrenItem,dateList);
                    childrenItem.put("isParent", (childrensList!=null&&childrensList.size()>0));
                    childrenItem.put("children", childrensList);
                    return childrenItem;
                })
                .collect(Collectors.toList());
        return childrens;
    }


    /**
	 * 导出
	 * @param cond
	 * @return
	 */
	@RequestMapping("/export")
	@ResponseBody
	public R export(@ModelAttribute TpShopRegisterPhaseSet cond){
        try {
            cond.setPage(0).setSize(999999);
            cond = setSeachSql(cond);
            //获取数据
            List<Map<String, Object>> listData = cond.queryMap();
            List<YsCol> listField = new ArrayList<>();
            listField.add(new YsCol().setName("阶段名称").setCode("phaseName"));
            listField.add(new YsCol().setName("阶段").setCode("phaseNum"));
            listField.add(new YsCol().setName("时效").setCode("workTime"));
            listField.add(new YsCol().setName("负责人").setCode("headUser"));
            listField.add(new YsCol().setName("负责部门").setCode("deptNameInfo"));
            listField.add(new YsCol().setName("平均时效").setCode("countNum"));
            ExportExcelUtils<TpShopRegisterPhaseSet> util = new ExportExcelUtils<>(new TpShopRegisterPhaseSet());
            
            String toFilePath = util.exportExcel(listData, listField, "注册跟踪阶段设置表");
            UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
            return R.ok(dto.getUrl());
        }catch (Exception e){
            e.printStackTrace();
            return R.error("导出失败，请稍后重试！");
        }
	}

    /**
     * 新增
     */
    @PostMapping("/add")
    @ResponseBody
    public R add(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {

            String setType = params.get("setType").toString();
            //如果新增的是分支集合类型，查询上下级是否是分支集合，要限制不能连续两个分支集合
            if(setType.equals("1")){
                int phaseNum = Integer.parseInt(params.get("phaseNum").toString());
                int parentId = Integer.parseInt(params.get("parentId").toString());
                List<TpShopRegisterPhaseSet> hasNeedUpdateList = new TpShopRegisterPhaseSet()
                        .where("A.ParentId = "+parentId)
                        .where("A.PhaseNum IN ("+(phaseNum-1)+ ","+ (phaseNum+1)+")")
                        .where("A.SetType = 1")
                        .queryList();
                if(hasNeedUpdateList!=null && hasNeedUpdateList.size()>0){
                    return R.error("无法新增，不能添加连续的分支集合！");
                }
            }
            //新增
            tpShopRegisterPhaseSetService.add(params);
            return R.ok("操作成功");
        }catch (Exception e){
            e.printStackTrace();
            return R.error("添加失败，请稍后重试！");
        }
    }

    /**
     * 修改
     */
    @PostMapping("/edit")
    @ResponseBody
    public R edit(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {
            String setType = params.get("setType").toString();
            //新的阶段号
            int phaseNum = Integer.parseInt(params.get("phaseNum").toString());
            //旧的阶段号
            int oldPhaseNum = Integer.parseInt(params.get("oldPhaseNum").toString());
            //如果修改的是分支集合类型，查询上下级是否是分支集合，要限制不能连续两个分支集合
            if(setType.equals("1") && phaseNum!=oldPhaseNum){
                int num1 = phaseNum-1;
                int num2 = phaseNum;
                int parentId = Integer.parseInt(params.get("parentId").toString());
                List<TpShopRegisterPhaseSet> hasNeedUpdateList = new TpShopRegisterPhaseSet()
                        .where("A.ParentId = "+parentId)
                        .where("A.PhaseNum IN ("+num1+ ","+ num2 +")")
                        .where("A.SetType = 1")
                        .queryList();
                if(hasNeedUpdateList!=null && hasNeedUpdateList.size()>0){
                    return R.error("无法修改，修改后的阶段顺序将会形成连续的分支集合，请重新设置阶段顺序！");
                }
            }

            tpShopRegisterPhaseSetService.edit(params);
            return R.ok("操作成功");
        }catch (Exception e){
            e.printStackTrace();
            return R.error("修改失败，请稍后重试！");
        }
    }

    /**
     * 删除前查询是否有正处于该阶段的任务
     */
    @PostMapping("/deleteTrueBefore")
    @ResponseBody
    public JSONObject deleteTrueBefore(HttpServletRequest request, HttpServletResponse response,
                        Long id,int phaseNum,long parentId) {
        JSONObject result = new JSONObject();
        try {
            TpShopRegisterPhaseRecord hasRecord = new TpShopRegisterPhaseRecord()
                    .setSetId(id)
                    .setSetType(0)
                    .where("(A.EndUser IS NULL OR A.EndUser = '')")
                    .queryFirst();
            if(hasRecord!=null){//有正处于该阶段的任务
                result.put("code",1);
            }else {
                result.put("code",0);
            }
            return result;

        }catch (Exception e){
            e.printStackTrace();
            result.put("code",9999);
            result.put("msg","删除失败，请稍后重试！");
            return result;
        }
    }

    /**
     * 删除
     */
    @PostMapping("/deleteTrue")
    @ResponseBody
    public R deleteTrue(Long id,int phaseNum,long parentId) {
        try {
            //删除
            tpShopRegisterPhaseSetService.deleteTrue(id,phaseNum,parentId);
            return R.ok("操作成功");

        }catch (Exception e){
            e.printStackTrace();
            return R.error("删除失败，请稍后重试！");
        }
    }


    /**
     * 获取数据
     */
    @PostMapping("/getParentList")
    @ResponseBody
    public JSONObject getParentList(HttpServletRequest request, HttpServletResponse response) {
        try {

            List<Map<String, Object>> allSetList = new TpShopRegisterPhaseSet()
                    .addField("A.PhaseName AS title")
                    .queryMap();

            //过滤只获取分支集合、任务分支类型的数据
            List<Map<String, Object>> parentList = allSetList.stream()
                    .filter(item -> item.get("setType").toString().equals("1") || item.get("setType").toString().equals("2"))
                    .collect(Collectors.toList());

            //递归查询
            List<Map<String, Object>> listData = parentList.stream().filter(item -> item.get("parentId").toString().equals("-1") )
                    .map(item -> {
                        List<Map<String, Object>> childrensList = getAddChildrens(item,parentList);
                        item.put("children", childrensList);
                        item.put("spread",true );
                        return item;
                    })
                    .collect(Collectors.toList());

            JSONObject result = new JSONObject();
            result.put("listData",listData);
            result.put("allSetList",allSetList);
            result.put("code",0);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("code",1);
            return result;
        }
    }

    /**
     * 查询子类数据
     * @param item
     * @param dateList
     * @return
     */
    public List<Map<String, Object>> getAddChildrens(Map<String, Object> item,List<Map<String, Object>> dateList){
        List<Map<String, Object>> childrens = dateList.stream()
                .filter(dataItem -> dataItem.get("parentId").toString().equals(item.get("id").toString()))
                .map(childrenItem -> {
                    item.put("spread",true );
                    List<Map<String, Object>> childrensList = getAddChildrens(childrenItem,dateList);
                    childrenItem.put("children", childrensList);
                    return childrenItem;
                })
                .collect(Collectors.toList());
        return childrens;
    }


    /**
     * 获取图例数据
     */
    @PostMapping("/getWorkFlowList")
    @ResponseBody
    public JSONObject getWorkFlowList(HttpServletRequest request, HttpServletResponse response) {
        try {
            JSONObject result = new JSONObject();
            List<TpShopRegisterPhaseSet> allSetList = new TpShopRegisterPhaseSet().queryList();
            if(allSetList!=null && allSetList.size()>0){
                //获取所有任务节点
                List<TpShopRegisterPhaseSet> pointList = allSetList.stream().filter( item-> item.getSetType()==0 ).collect(Collectors.toList());

                //获取所有任务节点的下一个任务
                List<Map<String,Long>> pointSideList = new ArrayList<>();
                for(TpShopRegisterPhaseSet setItem : allSetList){
                    if(setItem.getSetType()==0){
                        Long id = setItem.getId();
                        //获取下一级的数据id
                        List<TpShopRegisterPhaseSet> nextSetList = allSetList.stream()
                                .filter( item-> item.getParentId().equals(setItem.getParentId()) && item.getPhaseNum().equals(setItem.getPhaseNum()+1))
                                .collect(Collectors.toList());
                        pointSideList = getWorkFlowParent(nextSetList,pointSideList,id,setItem,allSetList);
                    }
                }
                result.put("pointList",pointList);
                result.put("pointSideList",pointSideList);
            }else {
                result.put("pointList",null);
                result.put("pointSideList",null);
            }
            result.put("code",0);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("code",1);
            return result;
        }
    }
    /**
     * 查询父类数据
     * @return
     */
    public List<Map<String,Long>> getWorkFlowParent(List<TpShopRegisterPhaseSet> nextSetList,List<Map<String,Long>> pointSideList, Long id,TpShopRegisterPhaseSet setItem, List<TpShopRegisterPhaseSet> allSetList){
        if(nextSetList!=null && nextSetList.size()>0){//如果有下一级
            pointSideList = getWorkFlowChildrens( pointSideList,nextSetList.get(0), id,allSetList );
        }else {//如果无下一级，且不是主流程，则查询父级的下一级
            if(setItem.getPhaseType()!=0){
                //父级
                List<TpShopRegisterPhaseSet> parentSetList = allSetList.stream().filter(item->item.getId().equals(setItem.getParentId())).collect(Collectors.toList());
                if(parentSetList.get(0).getSetType()==2){//如果父级是分支
                    //父级的父级
                    List<TpShopRegisterPhaseSet> pParentSetList = allSetList.stream().filter(item->item.getId().equals(parentSetList.get(0).getParentId())).collect(Collectors.toList());
                    //父级的父级的下一级
                    List<TpShopRegisterPhaseSet> parentNextSetList = allSetList.stream()
                            .filter(item->item.getParentId().equals(pParentSetList.get(0).getParentId()) && item.getPhaseNum()==pParentSetList.get(0).getPhaseNum()+1)
                            .collect(Collectors.toList());
                    pointSideList = getWorkFlowParent(parentNextSetList,pointSideList,id,pParentSetList.get(0),allSetList);
                }else {
                    //父级的下一级
                    List<TpShopRegisterPhaseSet> parentNextSetList = allSetList.stream()
                            .filter(item->item.getParentId().equals(parentSetList.get(0).getParentId()) && item.getPhaseNum()==parentSetList.get(0).getPhaseNum()+1)
                            .collect(Collectors.toList());
                    pointSideList = getWorkFlowParent(parentNextSetList,pointSideList,id,parentSetList.get(0),allSetList);
                }

            }

        }
        return pointSideList;
    }

    /**
     * 查询子类数据
     * @return
     */
    public List<Map<String,Long>> getWorkFlowChildrens( List<Map<String,Long>> pointSideList,TpShopRegisterPhaseSet nextSet, Long id,List<TpShopRegisterPhaseSet> allSetList ){
        if(nextSet.getSetType()==0){//如果下一级是阶段任务
            Map<String,Long> pointMsg = new HashMap<>();
            pointMsg.put("startPoint",id);
            pointMsg.put("endPoint",nextSet.getId());
            pointSideList.add(pointMsg);
        }else{//如果下一级是分支集合,则需要获取底下所有的分支中的第一个任务
            List<TpShopRegisterPhaseSet> nextSetFzList = allSetList.stream()
                    .filter( item-> item.getParentId().equals(nextSet.getId()))
                    .collect(Collectors.toList());
            if(nextSetFzList!=null && nextSetFzList.size()>0){
                for(TpShopRegisterPhaseSet setFzItem : nextSetFzList){
                    List<TpShopRegisterPhaseSet> nextSetRwList = allSetList.stream()
                            .filter( item-> item.getParentId().equals(setFzItem.getId()) && item.getPhaseNum()==1)
                            .collect(Collectors.toList());
                    if(nextSetRwList!=null && nextSetRwList.size()>0){
                        pointSideList = getWorkFlowChildrens( pointSideList,nextSetRwList.get(0), id,allSetList );
                    }
                }
            }
        }
        return pointSideList;
    }

}